package com.dingreading.cloud.mall.service.impl;

import com.dingreading.cloud.common.util.AccountUtil;
import com.dingreading.cloud.common.util.EnumOperationType;
import com.dingreading.cloud.mall.dto.GoodsTypeInfoDto;
import com.dingreading.cloud.mall.entity.GoodsType;
import com.dingreading.cloud.mall.entity.table.GoodsTypeTableDef;
import com.dingreading.cloud.mall.mapper.GoodsTypeMapper;
import com.dingreading.cloud.mall.service.GoodsTypeService;
import com.mybatisflex.core.query.QueryCondition;
import com.mybatisflex.core.query.QueryWrapper;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 服务层实现。
 *
 * @author Administrator
 * @since 2023-11-22
 */
@Service
public class GoodsTypeServiceImpl extends BaseServiceImpl<GoodsTypeMapper, GoodsType, GoodsTypeTableDef> implements GoodsTypeService {

    @Override
    protected GoodsTypeTableDef getTable() {
        return GoodsTypeTableDef.goodsType;
    }

    @Resource
    private GoodsTypeMapper goodsTypeMapper;

    @Override
    public List<GoodsTypeInfoDto> typeInfoListByGoodsIdAndEnabled(
            Long goodsId, Integer operationType, List<Integer> cooperationType, List<Long> subjectIdList
    ) {
        QueryCondition condition = QueryCondition.createEmpty();
        condition.and(table.goodsId.eq(goodsId))
                .and(table.enabled.eq(1));

        boolean easyProductJoinType = operationType.equals(EnumOperationType.EASY_PRODUCT_JOIN.getType());
        if (easyProductJoinType) {
            condition.and(AccountUtil.getOperationTypeSql(operationType));
            String sql = subjectIdList.stream().map(String::valueOf).collect(Collectors.joining("|"));
            condition.and("subject_type REGEXP '(^|,)(" + sql + ")(,|$)'");
        } else {
            if (operationType != null)
                condition.and(AccountUtil.getOperationTypeSql(operationType));
            if (cooperationType != null)
                condition.and(AccountUtil.getCooperationTypeSql(cooperationType));
        }

        QueryWrapper wrapper = QueryWrapper.create()
                .where(condition)
                .orderBy(table.comboType.asc(), table.orderNum.asc());
        return getMapper().selectListByQueryAs(wrapper, GoodsTypeInfoDto.class);
    }

    @Override
    public List<GoodsTypeInfoDto> typeInfoList(List<Long> goodsIdList, Integer operationType, List<Integer> cooperationType, List<Long> subjectIdList) {
        QueryCondition condition = QueryCondition.createEmpty();
        condition.and(table.goodsId.in(goodsIdList))
                .and(table.enabled.eq(1));

        boolean easyProductJoinType = operationType.equals(EnumOperationType.EASY_PRODUCT_JOIN.getType());
        if (easyProductJoinType) {
            condition.and(AccountUtil.getOperationTypeSql(operationType));
            String sql = subjectIdList.stream().map(String::valueOf).collect(Collectors.joining("|"));
            condition.and("subject_type REGEXP '(^|,)(" + sql + ")(,|$)'");
        } else {
            if (operationType != null)
                condition.and(AccountUtil.getOperationTypeSql(operationType));
            if (cooperationType != null)
                condition.and(AccountUtil.getCooperationTypeSql(cooperationType));
        }

        QueryWrapper wrapper = QueryWrapper.create()
                .select(table.id, table.goodsId, table.discountStatus, table.price)
                .from(table)
                .where(condition)
                .orderBy(table.comboType.asc(), table.orderNum.asc());
        return getMapper().selectListByQueryAs(wrapper, GoodsTypeInfoDto.class);
    }

    @Override
    public GoodsType getByGoodsIdAndGoodsTypeId(Long goodsId, Long goodsTypeId) {
        QueryCondition condition = QueryCondition.createEmpty();
        condition.and(table.goodsId.eq(goodsId))
                .and(table.id.eq(goodsTypeId));

        return getMapper().selectOneByCondition(condition);
    }


    @Override
    public List<GoodsType> maxUnitPrice(List<Long> goodsIdList, Integer operationType, List<Integer> cooperationTypeList, List<Long> subjectIdList) {
        String operationTypeSql = AccountUtil.getOperationTypeSql2(operationType);
        String cooperationTypeSql = AccountUtil.getCooperationTypeSql2(cooperationTypeList);
        boolean easyProductJoinType = operationType.equals(EnumOperationType.EASY_PRODUCT_JOIN.getType());
        String subjectTypeSql = "";
        if (CollectionUtils.isNotEmpty(subjectIdList)) {
            String subjectIdSql = subjectIdList.stream().map(String::valueOf).collect(Collectors.joining("|"));
            subjectTypeSql = "(^|,)(" + subjectIdSql + ")(,|$)";
        }
        return goodsTypeMapper.maxUnitPrice(goodsIdList, operationTypeSql, cooperationTypeSql, subjectTypeSql, easyProductJoinType);
    }

}
